#include "vl_node_prop.h"
#include <sstream>

using namespace VL;


/**
 * @Author: CimZzz
 * @Date: 2022-06-21 11:17:04
 * 
 * 构造方法
 */
NodeProp::NodeProp() : VLProp(VLProp::PropType::Node), propValue(nullptr), valueType(PropValueType::Void) {
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 11:18:02
 * 
 * 有参构造方法
 * @param value 值指针
 */
NodeProp::NodeProp(const std::shared_ptr<std::string>& value) : VLProp(VLProp::PropType::Node), propValue(nullptr), valueType(PropValueType::Void) {
	this->setValue(value);
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 11:18:02
 * 
 * 有参构造方法
 * @param value 值指针
 */
NodeProp::NodeProp(const std::string& value) : VLProp(VLProp::PropType::Node), propValue(nullptr), valueType(PropValueType::Void) {
	this->setValue(value);
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 14:28:16
 * 
 * 有参构造方法
 * @param value 字符串
 */
NodeProp::NodeProp(const char * value) : VLProp(VLProp::PropType::Node), propValue(nullptr), valueType(PropValueType::Void) {
	this->setValue(value);
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 11:18:02
 * 
 * 有参构造方法
 * @param value 布尔值
 */
NodeProp::NodeProp(const bool& value) : VLProp(VLProp::PropType::Node), propValue(nullptr), valueType(PropValueType::Void) {
	this->setValue(value);
}


/**
 * @Author: CimZzz
 * @Date: 2022-09-05 18:45:07
 * 
 * 有参构造方法
 * 
 * @param value 字节
 */
NodeProp::NodeProp(const int8_t& value) : VLProp(VLProp::PropType::Node), propValue(nullptr), valueType(PropValueType::Void) {
	this->setValue(value);
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 18:45:07
 * 
 * 有参构造方法
 * 
 * @param value 无符号字节
 */
NodeProp::NodeProp(const uint8_t& value) : VLProp(VLProp::PropType::Node), propValue(nullptr), valueType(PropValueType::Void) {
	this->setValue(value);
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 18:45:07
 * 
 * 有参构造方法
 * 
 * @param value 短整型
 */
NodeProp::NodeProp(const int16_t& value) : VLProp(VLProp::PropType::Node), propValue(nullptr), valueType(PropValueType::Void) {
	this->setValue(value);
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 18:45:07
 * 
 * 有参构造方法
 * 
 * @param value 无符号短整型
 */
NodeProp::NodeProp(const uint16_t& value) : VLProp(VLProp::PropType::Node), propValue(nullptr), valueType(PropValueType::Void) {
	this->setValue(value);
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 11:18:02
 * 
 * 有参构造方法
 * @param value 整数值
 */
NodeProp::NodeProp(const int32_t& value) : VLProp(VLProp::PropType::Node), propValue(nullptr), valueType(PropValueType::Void) {
	this->setValue(value);
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 11:18:02
 * 
 * 有参构造方法
 * @param value 无符号整数值
 */
NodeProp::NodeProp(const uint32_t& value) : VLProp(VLProp::PropType::Node), propValue(nullptr), valueType(PropValueType::Void) {
	this->setValue(value);
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 11:18:02
 * 
 * 有参构造方法
 * @param value 长整型
 */
NodeProp::NodeProp(const int64_t& value) : VLProp(VLProp::PropType::Node), propValue(nullptr), valueType(PropValueType::Void) {
	this->setValue(value);
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 11:18:02
 * 
 * 有参构造方法
 * @param value 无符号长整型
 */
NodeProp::NodeProp(const uint64_t& value) : VLProp(VLProp::PropType::Node), propValue(nullptr), valueType(PropValueType::Void) {
	this->setValue(value);
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 18:59:36
 * 
 * 设置值
 * @param value 值
 */
void NodeProp::setValue(const std::string & value) {
	this->propValue = std::shared_ptr<std::string>(new std::string(value));
	this->valueType = PropValueType::String;
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 11:18:37
 * 
 * 设置值
 * @param valuePtr 值指针
 */
void NodeProp::setValue(std::string* valuePtr) {
	this->propValue = std::shared_ptr<std::string>(valuePtr);
	this->valueType = PropValueType::String;
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 11:19:05
 * 
 * 设置值
 * @param valuePtr 值指针
 */
void NodeProp::setValue(std::shared_ptr<std::string> valuePtr) {
	this->propValue = valuePtr;
	this->valueType = PropValueType::String;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 11:46:46
 * 
 * 设置布尔值
 * @param boolean 布尔值
 */
void NodeProp::setValue(const bool& boolean) {
	this->propValue = std::shared_ptr<bool>(new bool(boolean));
	this->valueType = PropValueType::Boolean;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 18:47:47
 * 
 * 设置字节
 * @param value 字节
 */
void NodeProp::setValue(const int8_t& value) {
	this->propValue = std::shared_ptr<int8_t>(new int8_t(value));
	this->valueType = PropValueType::Byte;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 18:48:05
 * 
 * 设置无符号字节
 * @param value 无符号字节
 */
void NodeProp::setValue(const uint8_t& value) {
	this->propValue = std::shared_ptr<uint8_t>(new uint8_t(value));
	this->valueType = PropValueType::UByte;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 18:47:47
 * 
 * 设置短整型
 * @param value 短整型
 */
void NodeProp::setValue(const int16_t& value) {
	this->propValue = std::shared_ptr<int16_t>(new int16_t(value));
	this->valueType = PropValueType::Short;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 18:48:05
 * 
 * 设置无符号短整型
 * @param value 无符号短整型
 */
void NodeProp::setValue(const uint16_t& value) {
	this->propValue = std::shared_ptr<uint16_t>(new uint16_t(value));
	this->valueType = PropValueType::UShort;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 11:46:22
 * 
 * 设置整数值
 * @param number 整数值
 */
void NodeProp::setValue(const int32_t& number) {
	this->propValue = std::shared_ptr<int32_t>(new int32_t(number));
	this->valueType = PropValueType::Int;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 18:48:05
 * 
 * 设置无符号整型
 * @param value 无符号整型
 */
void NodeProp::setValue(const uint32_t& value) {
	this->propValue = std::shared_ptr<uint32_t>(new uint32_t(value));
	this->valueType = PropValueType::UInt;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 11:46:22
 * 
 * 设置长整数值
 * @param number 长整数值
 */
void NodeProp::setValue(const int64_t& number) {
	this->propValue = std::shared_ptr<int64_t>(new int64_t(number));
	this->valueType = PropValueType::Long;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 18:48:05
 * 
 * 设置无符号长整型
 * @param value 无符号长整型
 */
void NodeProp::setValue(const uint64_t& value) {
	this->propValue = std::shared_ptr<uint64_t>(new uint64_t(value));
	this->valueType = PropValueType::ULong;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 19:13:35
 * 
 * 二次解析字符串为对应值
 */
void NodeProp::parseStrValue() {
	if(this->valueType != PropValueType::String) {
		return;
	}
	auto strPtr = std::static_pointer_cast<std::string, void>(this->propValue);
	if(strPtr.get() == nullptr) {
		return;
	}

	auto str = *strPtr;
	auto strLength = str.length();
	auto matchValueType = PropValueType::Void;
	bool isTrue = false;
	int boolIdx = 0;
	bool isCompleted = false;
	int8_t c;
	uint8_t uc;
	int16_t s;
	uint16_t us;
	int32_t i;
	uint32_t ui;
	int64_t l;
	uint64_t ul;

	for(int idx = 0 ; idx < strLength ; idx ++) {
		char ch = str.at(idx);
		switch(matchValueType) {
			case PropValueType::Void: {
				if(ch >= '0' && ch <= '9') {
					// 数字 0-9, 匹配为字节
					uc = ch - '0';
					matchValueType = PropValueType::UByte;
					isCompleted = true;
					break;
				}
				if(ch == 't' || ch == 'T') {
					// 数字 0-9, 匹配为字节
					isTrue = true;
					matchValueType = PropValueType::Boolean;
					break;
				}
				if(ch == 'f' || ch == 'F') {
					// 数字 0-9, 匹配为字节
					isTrue = false;
					matchValueType = PropValueType::Boolean;
					break;
				}
				if(ch == '-') {
					// 可能是有符号整数
					idx ++;
					if(idx >= strLength) {
						return;
					}
					ch = str.at(idx);
					if(ch >= '0' && ch <= '9') {
						// 数字 0-9, 匹配为字节
						c = -(ch - '0');
						matchValueType = PropValueType::Byte;
						isCompleted = true;
						break;
					}
				}

				// 无匹配
				return;
			}
			case PropValueType::Boolean: {
				if(isTrue) {
					// 匹配 true
					switch(boolIdx) {
						case 0:
							if(ch != 'r' && ch != 'R') {
								return;
							}
							break;
						case 1:
							if(ch != 'u' && ch != 'U') {
								return;
							}
							break;
						case 2:
							if(ch != 'e' && ch != 'E') {
								return;
							}
							isCompleted = true;
							break;
						default:
						return;
					}
					boolIdx ++;
					break;
				} else {
					// 匹配 true
					switch(boolIdx) {
						case 0:
							if(ch != 'a' && ch != 'A') {
								return;
							}
							break;
						case 1:
							if(ch != 'l' && ch != 'L') {
								return;
							}
							break;
						case 2:
							if(ch != 's' && ch != 'S') {
								return;
							}
							break;
						case 3:
							if(ch != 'e' && ch != 'E') {
								return;
							}
							isCompleted = true;
							break;
						default:
						return;
					}
					boolIdx ++;
					break;
				}
			}
			case PropValueType::UByte: {
				if(ch >= '0' && ch <= '9') {
					uint8_t number = ch - '0';
					// 数字 0-9, 匹配为字节
					us = (uint16_t)uc * 10;
					if(us > UINT8_MAX) {
						us += number;
						matchValueType = PropValueType::UShort;
					} else {
						uc = (uint8_t)us + number;
					}
					break;
				}
				return;
			}
			case PropValueType::UShort: {
				if(ch >= '0' && ch <= '9') {
					uint8_t number = ch - '0';
					// 数字 0-9, 匹配为字节
					ui = (uint16_t)us * 10;
					if(ui > UINT16_MAX) {
						ui += number;
						matchValueType = PropValueType::UInt;
					} else {
						us = (uint16_t)ui + number;
					}
					break;
				}
				return;
			}
			case PropValueType::UInt: {
				if(ch >= '0' && ch <= '9') {
					uint8_t number = ch - '0';
					// 数字 0-9, 匹配为字节
					ul = (uint32_t)ui * 10;
					if(ul > UINT32_MAX) {
						ul += number;
						matchValueType = PropValueType::ULong;
					} else {
						ui = (uint32_t)ul + number;
					}
					break;
				}
				return;
			}
			case PropValueType::ULong: {
				if(ch >= '0' && ch <= '9') {
					uint8_t number = ch - '0';
					// 数字 0-9, 匹配为字节
					ul = ul * 10 + number;
					break;
				}
				return;
			}


			case PropValueType::Byte: {
				if(ch >= '0' && ch <= '9') {
					int8_t number = ch - '0';
					// 数字 0-9, 匹配为字节
					s = (int16_t)c * 10;
					if(s < INT8_MIN) {
						s -= number;
						matchValueType = PropValueType::Short;
					} else {
						c = (int8_t)s - number;
					}
					break;
				}
				return;
			}
			case PropValueType::Short: {
				if(ch >= '0' && ch <= '9') {
					int8_t number = ch - '0';
					// 数字 0-9, 匹配为字节
					i = (int16_t)s * 10;
					if(i > INT16_MIN) {
						i -= number;
						matchValueType = PropValueType::Int;
					} else {
						s = (int16_t)i - number;
					}
					break;
				}
				return;
			}
			case PropValueType::Int: {
				if(ch >= '0' && ch <= '9') {
					int8_t number = ch - '0';
					// 数字 0-9, 匹配为字节
					l = (int32_t)i * 10;
					if(l > INT32_MIN) {
						l -= number;
						matchValueType = PropValueType::Long;
					} else {
						i = (int32_t)l - number;
					}
					break;
				}
				return;
			}
			case PropValueType::Long: {
				if(ch >= '0' && ch <= '9') {
					uint8_t number = ch - '0';
					// 数字 0-9, 匹配为字节
					l = l * 10 - number;
					break;
				}
				return;
			}
			default:
				return;
		}


	}

	if(!isCompleted) {
		return;
	}

	switch (matchValueType) {
		case Boolean :
			this->setValue(isTrue);
			break;
		case Byte :
			this->setValue(c);
			break;
		case UByte :
			this->setValue(uc);
			break;
		case Short :
			this->setValue(s);
			break;
		case UShort :
			this->setValue(us);
			break;
		case Int :
			this->setValue(i);
			break;
		case UInt :
			this->setValue(ui);
			break;
		case Long :
			this->setValue(l);
			break;
		case ULong :
			this->setValue(ul);
			break;
		default:
			break;
	}
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 17:45:48
 * 
 * 获取属性值
 * @return 属性值
 */
std::string NodeProp::getValue() {
	if(this->valueType == PropValueType::String) {
		auto strPtr = std::static_pointer_cast<std::string, void>(this->propValue);
		return strPtr.get() == nullptr ? "" : *strPtr;
	}
	return "";
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 11:48:21
 * 
 * 获取布尔值, 缺省为 false
 * 
 * @param defaultValue 缺省值
 * 
 * @return 布尔值
 */
bool NodeProp::getBoolean(bool defaultValue) {
	if(this->valueType == PropValueType::Boolean) {
		auto boolPtr = std::static_pointer_cast<bool, void>(this->propValue);
		return boolPtr.get() == nullptr ? defaultValue : *boolPtr;
	}
	return defaultValue;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 18:29:21
 * 
 * 获取字节, 缺省值为 0
 * 
 * @param defaultValue 缺省值
 * 
 * @return 字节值
 */
int8_t NodeProp::getByte(int8_t defaultValue) {
	int8_t value = defaultValue;

	switch(this->valueType) {
		case PropValueType::Byte:
			value = *std::static_pointer_cast<int8_t, void>(this->propValue);
			break;
		case PropValueType::UByte:
			value = *std::static_pointer_cast<uint8_t, void>(this->propValue);
			break;
		case PropValueType::Short:
			value = *std::static_pointer_cast<int16_t, void>(this->propValue);
			break;
		case PropValueType::UShort:
			value = *std::static_pointer_cast<uint16_t, void>(this->propValue);
			break;
		case PropValueType::Int:
			value = *std::static_pointer_cast<int32_t, void>(this->propValue);
			break;
		case PropValueType::UInt:
			value = *std::static_pointer_cast<uint32_t, void>(this->propValue);
			break;
		case PropValueType::Long:
			value = *std::static_pointer_cast<int64_t, void>(this->propValue);
			break;
		case PropValueType::ULong:
			value = *std::static_pointer_cast<uint64_t, void>(this->propValue);
			break;
		default:
			break;
	}

	return value;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 18:28:22
 * 
 * 获取无符号字节, 缺省值为 0
 * 
 * @param defaultValue 缺省值
 * 
 * @return 无符号字节
 */
uint8_t NodeProp::getUByte(uint8_t defaultValue) {
	uint8_t value = defaultValue;

	switch(this->valueType) {
		case PropValueType::Byte:
			value = *std::static_pointer_cast<int8_t, void>(this->propValue);
			break;
		case PropValueType::UByte:
			value = *std::static_pointer_cast<uint8_t, void>(this->propValue);
			break;
		case PropValueType::Short:
			value = *std::static_pointer_cast<int16_t, void>(this->propValue);
			break;
		case PropValueType::UShort:
			value = *std::static_pointer_cast<uint16_t, void>(this->propValue);
			break;
		case PropValueType::Int:
			value = *std::static_pointer_cast<int32_t, void>(this->propValue);
			break;
		case PropValueType::UInt:
			value = *std::static_pointer_cast<uint32_t, void>(this->propValue);
			break;
		case PropValueType::Long:
			value = *std::static_pointer_cast<int64_t, void>(this->propValue);
			break;
		case PropValueType::ULong:
			value = *std::static_pointer_cast<uint64_t, void>(this->propValue);
			break;
		default:
			break;
	}

	return value;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 14:31:11
 * 
 * 获取短整型, 缺省值为 0
 * 
 * @param defaultValue 缺省值
 * 
 * @return 短整型
 */
int16_t NodeProp::getShort(int16_t defaultValue) {
	int16_t value = defaultValue;

	switch(this->valueType) {
		case PropValueType::Byte:
			value = *std::static_pointer_cast<int8_t, void>(this->propValue);
			break;
		case PropValueType::UByte:
			value = *std::static_pointer_cast<uint8_t, void>(this->propValue);
			break;
		case PropValueType::Short:
			value = *std::static_pointer_cast<int16_t, void>(this->propValue);
			break;
		case PropValueType::UShort:
			value = *std::static_pointer_cast<uint16_t, void>(this->propValue);
			break;
		case PropValueType::Int:
			value = *std::static_pointer_cast<int32_t, void>(this->propValue);
			break;
		case PropValueType::UInt:
			value = *std::static_pointer_cast<uint32_t, void>(this->propValue);
			break;
		case PropValueType::Long:
			value = *std::static_pointer_cast<int64_t, void>(this->propValue);
			break;
		case PropValueType::ULong:
			value = *std::static_pointer_cast<uint64_t, void>(this->propValue);
			break;
		default:
			break;
	}

	return value;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 14:31:11
 * 
 * 获取无符号短整型, 缺省值为 0
 * 
 * @param defaultValue 缺省值
 * 
 * @return 无符号短整型
 */
uint16_t NodeProp::getUShort(uint16_t defaultValue) {
	uint16_t value = defaultValue;

	switch(this->valueType) {
		case PropValueType::Byte:
			value = *std::static_pointer_cast<int8_t, void>(this->propValue);
			break;
		case PropValueType::UByte:
			value = *std::static_pointer_cast<uint8_t, void>(this->propValue);
			break;
		case PropValueType::Short:
			value = *std::static_pointer_cast<int16_t, void>(this->propValue);
			break;
		case PropValueType::UShort:
			value = *std::static_pointer_cast<uint16_t, void>(this->propValue);
			break;
		case PropValueType::Int:
			value = *std::static_pointer_cast<int32_t, void>(this->propValue);
			break;
		case PropValueType::UInt:
			value = *std::static_pointer_cast<uint32_t, void>(this->propValue);
			break;
		case PropValueType::Long:
			value = *std::static_pointer_cast<int64_t, void>(this->propValue);
			break;
		case PropValueType::ULong:
			value = *std::static_pointer_cast<uint64_t, void>(this->propValue);
			break;
		default:
			break;
	}

	return value;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 11:49:16
 * 
 * 获取整数值, 缺省为 0
 * 
 * @param defaultValue 缺省值
 * 
 * @return 整数值
 */
int32_t NodeProp::getInt(int defaultValue) {
	int32_t value = defaultValue;

	switch(this->valueType) {
		case PropValueType::Byte:
			value = *std::static_pointer_cast<int8_t, void>(this->propValue);
			break;
		case PropValueType::UByte:
			value = *std::static_pointer_cast<uint8_t, void>(this->propValue);
			break;
		case PropValueType::Short:
			value = *std::static_pointer_cast<int16_t, void>(this->propValue);
			break;
		case PropValueType::UShort:
			value = *std::static_pointer_cast<uint16_t, void>(this->propValue);
			break;
		case PropValueType::Int:
			value = *std::static_pointer_cast<int32_t, void>(this->propValue);
			break;
		case PropValueType::UInt:
			value = *std::static_pointer_cast<uint32_t, void>(this->propValue);
			break;
		case PropValueType::Long:
			value = *std::static_pointer_cast<int64_t, void>(this->propValue);
			break;
		case PropValueType::ULong:
			value = *std::static_pointer_cast<uint64_t, void>(this->propValue);
			break;
		default:
			break;
	}

	return value;
}


/**
 * @Author: CimZzz
 * @Date: 2022-09-05 14:27:01
 * 
 * 获取无符号整数值, 缺省为 0
 * 
 * @param defaultValue 缺省值
 * 
 * @return 整数值
 */
uint32_t NodeProp::getUInt(uint32_t defaultValue) {
	uint32_t value = defaultValue;

	switch(this->valueType) {
		case PropValueType::Byte:
			value = *std::static_pointer_cast<int8_t, void>(this->propValue);
			break;
		case PropValueType::UByte:
			value = *std::static_pointer_cast<uint8_t, void>(this->propValue);
			break;
		case PropValueType::Short:
			value = *std::static_pointer_cast<int16_t, void>(this->propValue);
			break;
		case PropValueType::UShort:
			value = *std::static_pointer_cast<uint16_t, void>(this->propValue);
			break;
		case PropValueType::Int:
			value = *std::static_pointer_cast<int32_t, void>(this->propValue);
			break;
		case PropValueType::UInt:
			value = *std::static_pointer_cast<uint32_t, void>(this->propValue);
			break;
		case PropValueType::Long:
			value = *std::static_pointer_cast<int64_t, void>(this->propValue);
			break;
		case PropValueType::ULong:
			value = *std::static_pointer_cast<uint64_t, void>(this->propValue);
			break;
		default:
			break;
	}

	return value;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 18:30:14
 * 
 * 获取长整型, 缺省值为 0
 * 
 * @param defaultValue 缺省值
 * 
 * @return 长整型
 */
int64_t NodeProp::getLong(int64_t defaultValue) {
	int64_t value = defaultValue;

	switch(this->valueType) {
		case PropValueType::Byte:
			value = *std::static_pointer_cast<int8_t, void>(this->propValue);
			break;
		case PropValueType::UByte:
			value = *std::static_pointer_cast<uint8_t, void>(this->propValue);
			break;
		case PropValueType::Short:
			value = *std::static_pointer_cast<int16_t, void>(this->propValue);
			break;
		case PropValueType::UShort:
			value = *std::static_pointer_cast<uint16_t, void>(this->propValue);
			break;
		case PropValueType::Int:
			value = *std::static_pointer_cast<int32_t, void>(this->propValue);
			break;
		case PropValueType::UInt:
			value = *std::static_pointer_cast<uint32_t, void>(this->propValue);
			break;
		case PropValueType::Long:
			value = *std::static_pointer_cast<int64_t, void>(this->propValue);
			break;
		case PropValueType::ULong:
			value = *std::static_pointer_cast<uint64_t, void>(this->propValue);
			break;
		default:
			break;
	}

	return value;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 18:31:34
 * 
 * 获取无符号长整型, 缺省值为 0
 * 
 * @param defaultValue 缺省值
 * 
 * @return 无符号长整型
 */
uint64_t NodeProp::getULong(uint64_t defaultValue) {
	uint64_t value = defaultValue;

	switch(this->valueType) {
		case PropValueType::Byte:
			value = *std::static_pointer_cast<int8_t, void>(this->propValue);
			break;
		case PropValueType::UByte:
			value = *std::static_pointer_cast<uint8_t, void>(this->propValue);
			break;
		case PropValueType::Short:
			value = *std::static_pointer_cast<int16_t, void>(this->propValue);
			break;
		case PropValueType::UShort:
			value = *std::static_pointer_cast<uint16_t, void>(this->propValue);
			break;
		case PropValueType::Int:
			value = *std::static_pointer_cast<int32_t, void>(this->propValue);
			break;
		case PropValueType::UInt:
			value = *std::static_pointer_cast<uint32_t, void>(this->propValue);
			break;
		case PropValueType::Long:
			value = *std::static_pointer_cast<int64_t, void>(this->propValue);
			break;
		case PropValueType::ULong:
			value = *std::static_pointer_cast<uint64_t, void>(this->propValue);
			break;
		default:
			break;
	}

	return value;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 11:50:02
 * 
 * 判断是否为整数
 * 
 * @return 如果是返回 true
 */
bool NodeProp::isInt() {
	return this->valueType == PropValueType::Byte ||
		this->valueType == PropValueType::Short ||
		this->valueType == PropValueType::Int ||
		this->valueType == PropValueType::Long ||
		this->isUInt();
}


/**
 * @Author: CimZzz
 * @Date: 2022-09-05 14:24:28
 * 
 * 判断是否为无符号整数
 * 
 * @return 如果是无符号整数返回 true
 */
bool NodeProp::isUInt() {
	return this->valueType == PropValueType::UByte ||
		this->valueType == PropValueType::UShort ||
		this->valueType == PropValueType::UInt ||
		this->valueType == PropValueType::ULong;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 11:50:22
 * 
 * 判断是否为布尔值
 * 
 * @return 如果是返回 true
 */
bool NodeProp::isBoolean() {
	return this->valueType == PropValueType::Boolean;
}

/**
 * @Author: CimZzz
 * @Date: 2022-09-05 11:50:58
 * 
 * 判断是否为字符串
 * 
 * @return 如果是返回 true
 */
bool NodeProp::isString() {
	return this->valueType == PropValueType::String;
}


/**
 * @Author: CimZzz
 * @Date: 2022-06-30 18:22:06
 * 
 * 比较两个 Array 之间的区别
 * @param prop 属性指针
 * @return 如果相同返回 true
 */
bool NodeProp::diff(VLProp* prop) {
	if(prop == nullptr || prop->getType() != this->getType()) {
		return false;
	}

	NodeProp* nodeProp = (NodeProp*) prop;
	if(nodeProp->valueType != this->valueType) {
		return false;
	}

	switch(this->valueType) {
		case PropValueType::Int: {
			auto intPtr1 = std::static_pointer_cast<int32_t, void>(this->propValue);
			auto intPtr2 = std::static_pointer_cast<int32_t, void>(nodeProp->propValue);
			if(*intPtr1 != *intPtr2) {
				return false;
			}
			break;
		}
		case PropValueType::String : {
			auto strPtr1 = std::static_pointer_cast<std::string, void>(this->propValue);
			auto strPtr2 = std::static_pointer_cast<std::string, void>(nodeProp->propValue);
			if(*strPtr1 != *strPtr2) {
				return false;
			}
			break;
		}
		case PropValueType::Boolean : {
			auto boolPtr1 = std::static_pointer_cast<bool, void>(this->propValue);
			auto boolPtr2 = std::static_pointer_cast<bool, void>(nodeProp->propValue);
			if(*boolPtr1 != *boolPtr2) {
				return false;
			}
			break;
		}
		default:
			break;
	}

	return true;
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 11:04:46
 * 
 * 构建属性打印信息
 */
std::string NodeProp::buildPropPrintInfo() {
	std::stringstream stream;
	stream << "(";
	if(this->getName() != "") {
		stream << "name: " << this->getName() << ", ";
	}
	stream << "type: ";
	switch(this->valueType) {
		case PropValueType::String : {
			stream << "string, value: ";
			auto strPtr = std::static_pointer_cast<std::string, void>(this->propValue);
			if(strPtr.get() == nullptr) {
				stream << "nullptr";
			} else {
				stream << *strPtr;
			}
			break;
		}
		case PropValueType::Boolean : {
			stream << "bool, value: ";
			auto boolPtr = std::static_pointer_cast<bool, void>(this->propValue);
			if(boolPtr.get() == nullptr) {
				stream << "nullptr";
			} else {
				stream << (*boolPtr ? "true" : "false");
			}
			break;
		}
		case PropValueType::Byte : {
			stream << "byte, value: ";
			auto dataPtr = std::static_pointer_cast<int8_t, void>(this->propValue);
			if(dataPtr.get() == nullptr) {
				stream << "nullptr";
			} else {
				stream << *dataPtr;
			}
			break;
		}
		case PropValueType::UByte : {
			stream << "unsigned byte, value: ";
			auto dataPtr = std::static_pointer_cast<uint8_t, void>(this->propValue);
			if(dataPtr.get() == nullptr) {
				stream << "nullptr";
			} else {
				stream << *dataPtr;
			}
			break;
		}
		case PropValueType::Short : {
			stream << "int16_t, value: ";
			auto dataPtr = std::static_pointer_cast<int16_t, void>(this->propValue);
			if(dataPtr.get() == nullptr) {
				stream << "nullptr";
			} else {
				stream << *dataPtr;
			}
			break;
		}
		case PropValueType::UShort : {
			stream << "uint16_t, value: ";
			auto dataPtr = std::static_pointer_cast<uint16_t, void>(this->propValue);
			if(dataPtr.get() == nullptr) {
				stream << "nullptr";
			} else {
				stream << *dataPtr;
			}
			break;
		}
		case PropValueType::Int : {
			stream << "int, value: ";
			auto dataPtr = std::static_pointer_cast<int32_t, void>(this->propValue);
			if(dataPtr.get() == nullptr) {
				stream << "nullptr";
			} else {
				stream << *dataPtr;
			}
			break;
		}
		case PropValueType::UInt : {
			stream << "unsigned int, value: ";
			auto dataPtr = std::static_pointer_cast<uint32_t, void>(this->propValue);
			if(dataPtr.get() == nullptr) {
				stream << "nullptr";
			} else {
				stream << *dataPtr;
			}
			break;
		}
		case PropValueType::Long : {
			stream << "long, value: ";
			auto dataPtr = std::static_pointer_cast<int64_t, void>(this->propValue);
			if(dataPtr.get() == nullptr) {
				stream << "nullptr";
			} else {
				stream << *dataPtr;
			}
			break;
		}
		case PropValueType::ULong : {
			stream << "unsigned long, value: ";
			auto dataPtr = std::static_pointer_cast<uint64_t, void>(this->propValue);
			if(dataPtr.get() == nullptr) {
				stream << "nullptr";
			} else {
				stream << *dataPtr;
			}
			break;
		}
		case PropValueType::Void :
			stream << "void";
			stream << ")";
			return stream.str();
	}
	stream << ")";
	return stream.str();
}